﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization;

namespace ANDMoudel
{
    public partial class ANDweigh : UserControl
    {
        public NewSerialPort ANDserial;
        public RetWeight ContempWeight;
        private DateTime lastupdatetime = new DateTime();
        private bool issendClear = false;
        public bool ConnectionStatus { get; set; }
        public ANDweigh()
        {
            InitializeComponent();
            if (!IsDesignMode)
            {
                NewSerialPort serialport = new NewSerialPort(name + "_And");
                ANDserial = serialport;
                Name = ANDserial.Name;
                Task.Factory.StartNew(() =>
                {
                    while (true)
                    {
                        Thread.Sleep(10);
                        try
                        {
                            if (!ANDserial.IsOpen)
                                ANDserial.Open();
                        }
                        catch { }
                        TimeSpan timeSpan = DateTime.Now - lastupdatetime;
                        if (timeSpan.TotalMilliseconds > 1000)
                        {
                            ConnectionStatus = false;
                        }
                        else
                        {
                            ConnectionStatus = true;
                        }
                    }
                }, TaskCreationOptions.LongRunning);
                ANDserial.OnReceiveData += ANDserial_OnReceiveData;
            }
        }

        public class RetWeight
        {
            internal RetWeight(bool isstable, string weight)
            {
                Weight = weight;
                IsStable = isstable;
            }
            public string Weight { get; }
            public bool IsStable { get; }

        }

        private void ANDweigh_Load(object sender, EventArgs e)
        {

        }

        public ANDweigh(NewSerialPort serialport)
        {
            InitializeComponent();
            ANDserial = serialport;
            Name = ANDserial.Name;
            ANDserial.OnReceiveData += ANDserial_OnReceiveData;
          
        }

        public ANDweigh(string name)
        {
            InitializeComponent();
            NewSerialPort serialport = new NewSerialPort(name + "_And");
            ANDserial = serialport;
            Name = ANDserial.Name;
            Task.Factory.StartNew(() =>
            {
                while (true)
                {
                    Thread.Sleep(10);
                    try
                    {
                        if (!ANDserial.IsOpen)
                            ANDserial.Open();
                    }
                    catch { }
                    TimeSpan timeSpan = DateTime.Now - lastupdatetime;
                    if (timeSpan.TotalMilliseconds > 1000)
                    {
                        ConnectionStatus = false;
                    }
                    else
                    {
                        ConnectionStatus = true;
                    }
                }
            }, TaskCreationOptions.LongRunning);
            ANDserial.OnReceiveData += ANDserial_OnReceiveData;

        }


        private void ANDserial_OnReceiveData(string obj)
        {
            if (obj.Contains("@RE"))
                return;
            lastupdatetime = DateTime.Now;
            if (issendClear)  //正在发送清零指令的时候不接受
                return;
            ContempWeight = ConvertString(obj);
        }



        /// <summary>
        /// 开机
        /// </summary>
        /// <param name="time">等待时间</param>
        public void PowerON(int time)
        {
            if (ANDserial == null)
                return;
            if (ANDserial.IsOpen)
            {
                ANDserial.SendMessage("ON\r\n");
                Thread.Sleep(time);   //停留5秒钟开机
            }
        }


        public bool IsPowerON()
        {
            if (GetWeightInstant(1000) == null)
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        public void PowerOFF()
        {
            if (ANDserial == null)
                return;
            if (ANDserial.IsOpen)
                ANDserial.SendMessage("OFF\r\n");
        }

        /// <summary>
        /// 获得及时称重值
        /// </summary>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public string GetWeightInstant(int timeout)
        {
            if (ANDserial == null)
                return null;
            return ContempWeight.Weight;
        }

        /// <summary>
        /// 获取稳定称重值
        /// </summary>
        /// <param name="timeout"></param>
        /// <returns></returns>
        public string GetWeightStable(int timeout)
        {
            if (ANDserial == null|| ContempWeight==null)
                return null;
            int c = 0;
            while (true)
            {
                if (ContempWeight.IsStable)
                {
                    return ContempWeight.Weight;
                }
                Thread.Sleep(100);
                c++;
                if (c > timeout / 100)
                {
                    return null;
                }
            }
        }

        /// <summary>
        /// 清零-有超时（不建议使用）
        /// </summary>
        /// <param name="milliSenconds"></param>
        /// <returns></returns>
        /// 
        [Obsolete("方法已经过期",true)]
        public bool Zero(int milliSenconds)
        {
            int timeout = 0;
            if (ANDserial == null)
                return false;
            ANDserial.SendMessage("R\r\n");
            while (String.IsNullOrEmpty(ANDserial.SendBackMessageInstant("Q\r\n", 100)) && timeout < milliSenconds / 100)
            {
                Thread.Sleep(5);
                timeout++;
            }
            if (timeout >= milliSenconds / 100)
            {
                return false;
            }
            else
            {
                return true;
            }
        }



        int isZero = 0;//0：正常状态  1：清零中  -1：清零失败
        private readonly object obj_zero_lock = new object();
        public void ZeroV(int timeout)
        {
            issendClear = true;
            isZero = 1;
            if (ANDserial == null)
            {
                isZero = -1;
                return;
            }
            try
            {
                ANDserial.SendMessage("R\r\n");
                Thread.Sleep(400);
            }
            catch
            {
                issendClear = false;
                isZero = -1;
                return;
            }
            ContempWeight = null;
            issendClear = false;
            int c = 0;
            while (true)
            {
                if (ContempWeight != null)
                {
                    isZero = 0;
                    break;
                }
                if (!this.InvokeRequired)
                {
                    Application.DoEvents();
                }
                Thread.Sleep(100);
                c++;
                if (c > timeout / 100)
                {
                    isZero = -1;
                    break;
                }
            }
        }

        private RetWeight ConvertString(string content)
        {

            if (string.IsNullOrEmpty(content))
                return null;
            string ret = "";
            if (content.Contains("ST,"))
            {
                char[] chenzhong = content.Split(',')[1].ToCharArray(0, 9);
                for (int i = 0; i < 9; i++)
                {
                    ret += chenzhong[i];
                }
                return new RetWeight(true, ret);
                
            }
            else if (content.Contains("US,"))
            {
                char[] chenzhong = content.Split(',')[1].ToCharArray(0, 9);
                for (int i = 0; i < 9; i++)
                {
                    ret += chenzhong[i];
                }
                return new RetWeight(false, ret);
            }
            else
            {
                return null;
            }
        }


        private void btnSwitchOn_Click(object sender, EventArgs e)
        {
            PowerON(10000);
        }

        private void btnSwitchOff_Click(object sender, EventArgs e)
        {
            PowerOFF();
        }

        private void btnRealTimeWeight_Click(object sender, EventArgs e)
        {
            //string ret = GetWeightInstant(1000);
            //if (!string.IsNullOrEmpty(ret))
            //    label6.Text = ret;
            //else
            //    label6.Text = "err";
        }

        private void btnStableTimeWeight_Click(object sender, EventArgs e)
        {
            textBox2.Text = "Waitting...";
            Application.DoEvents();
            string ret = GetWeightStable(3000);
            if (!string.IsNullOrEmpty(ret))
                textBox2.Text = ret;
            else
                textBox2.Text = "err";
        }

        private void btnReset_Click(object sender, EventArgs e)
        {
            ZeroV(4000);
        }

        private void btnSerialPortSetting_Click(object sender, EventArgs e)
        {
            Form form = new Form();
            form.AutoSize = true;
            form.Text = ANDserial.Name;
            form.Controls.Add(ANDserial);
            form.FormClosing += new FormClosingEventHandler(form_FormClosing);
            form.ShowDialog();
        }

        private void form_FormClosing(object sender, FormClosingEventArgs e)
        {
            ((Form)sender).Controls.Clear();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            try
            {
                if (ConnectionStatus)
                {
                    label8.Text = "在线";
                    label8.ForeColor = Color.LimeGreen;
                }
                else
                {
                    label8.Text = "离线";
                    label8.ForeColor = Color.Red;
                }
                if (ANDserial != null)
                {
                    //label1.Text = "AND称重器" + $"({ANDserial.Name})";
                    if (ANDserial.IsOpen)
                    {
                        this.BackColor = Color.GreenYellow;
                        label5.Text = ANDserial.Setting._port + "-已打开";
                        if (isZero == 0)
                        {
                            if (ContempWeight == null)
                            {
                                label7.Text = " ";
                                label6.Text = "Init";
                            }
                            else
                            {
                                label6.Text = ContempWeight.Weight + "g";
                                if (ContempWeight.IsStable)
                                {
                                    label7.Text = "°";
                                }
                                else
                                {
                                    label7.Text = " ";
                                }
                            }
                        }
                        else if (isZero == 1)
                            label6.Text = "Clearing";
                        else
                        {
                            label6.Text = "ClearFail";
                        }
                    }
                    else
                    {
                        this.BackColor = Color.LightGray;
                        label5.Text = "已关闭";
                    }
                }
            }
            catch { }
        }

        private void ANDweigh_ParentChanged(object sender, EventArgs e)
        {
            if (!IsDesignMode)
            {
                if (Parent != null)
                {
                    timer1.Start();
                }
                else
                {
                    timer1.Stop();
                }

                if (this.ParentForm != null)
                {
                    ParentForm.FormClosing += new FormClosingEventHandler(ParentForm_FormClosing);
                    ParentForm.AutoSize = true;
                    ParentForm.Text = Name;

                }
                else
                {

                }
            }
        }

        private  bool IsDesignMode
        {
            get
            {
                bool returnFlag = false;
                if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
                {
                    returnFlag = true;
                }
                else if (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv")
                {
                    returnFlag = true;
                }
                return returnFlag;
            }
        }

        private void ParentForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (ParentForm != null)
                ParentForm.Controls.Clear();
        }

        private void panel2_Paint(object sender, PaintEventArgs e)
        {

        }



      
    }


}
